package provider

import (
	"fmt"
	"os"
	"strings"
	"time"

	"code.bydev.io/cht/customer/kyc_admin_service/internal/pkg/kycprovider/dto"
	"github.com/speps/go-hashids"
	"go.uber.org/zap"
)

func TimeCost(log *zap.Logger, tag string) func() {
	start := time.Now()
	return func() {
		tc := time.Since(start)
		if log != nil {
			log.Info(fmt.Sprintf("%s timecost= %v\n", tag, tc))
		}
	}
}

var docTypeMap map[string]dto.DocType

func init() {
	docTypeMap = map[string]dto.DocType{
		// Sumsub
		"1_id_card":   dto.ID,
		"1_passport":  dto.Passport,
		"1_driver":    dto.DrivingLicense,
		"1_recidence": dto.LivingPermits,
		"1_bill":      dto.Bill,
		"1_BVN":       dto.BVN,
		"1_residence": dto.LivingPermits,

		// Jumio
		"2_ID_CARD":         dto.ID,
		"2_DRIVING_LICENSE": dto.DrivingLicense,
		"2_PASSPORT":        dto.Passport,
		// jumio Level 2
		"2_CC":     dto.DocTypeCC,
		"2_BS":     dto.DocTypeBS,
		"2_IC":     dto.DocTypeIC,
		"2_UB":     dto.DocTypeUB,
		"2_CAAP":   dto.DocTypeCAAP,
		"2_CRC":    dto.DocTypeCRC,
		"2_CCS":    dto.DocTypeCCS,
		"2_LAG":    dto.DocTypeLAG,
		"2_LOAP":   dto.DocTypeLOAP,
		"2_MOAP":   dto.DocTypeMOAP,
		"2_TR":     dto.DocTypeTR,
		"2_VT":     dto.DocTypeVT,
		"2_VC":     dto.DocTypeVC,
		"2_STUC":   dto.DocTypeSTUC,
		"2_HCC":    dto.DocTypeHCC,
		"2_CB":     dto.DocTypeCB,
		"2_SENC":   dto.DocTypeSENC,
		"2_MEDC":   dto.DocTypeMEDC,
		"2_BC":     dto.DocTypeBC,
		"2_WWCC":   dto.DocTypeWWCC,
		"2_SS":     dto.DocTypeSS,
		"2_TAC":    dto.DocTypeTAC,
		"2_SEL":    dto.DocTypeSEL,
		"2_PB":     dto.DocTypePB,
		"2_SSC":    dto.DocTypeSSC,
		"2_CUSTOM": dto.DocTypeCUSTOM,
		"2_OTHER":  dto.DocTypeOTHER,
	}
}

func GetUnifiedDocType(docType string, provider dto.KYCProvider) dto.DocType {
	docKey := fmt.Sprintf("%d_%s", int(provider), docType)
	if ret, ok := docTypeMap[docKey]; ok {
		return ret
	}

	return dto.UndefinedDocType
}

func GetDocTypeDesc(provider dto.KYCProvider, dt dto.DocType) string {
	if provider == dto.ProviderSumSub {
		switch dt {
		case dto.UndefinedDocType:
			return dto.DocumentTypeUnknown.String()
		case dto.ID:
			return dto.DocumentTypeID.String()
		case dto.Passport:
			return dto.DocumentTypePassport.String()
		case dto.DrivingLicense:
			return dto.DocumentTypeDriver.String()
		case dto.LivingPermits:
			return dto.DocumentTypeResidence.String()
		case dto.Bill:
			return dto.DocumentTypeBill.String()
		case dto.BVN:
			return dto.DocumentTypeBVN.String()
		}
	} else if provider == dto.ProviderOnfido {
		switch dt {
		case dto.ID:
			return dto.DocumentTypeID.String()
		case dto.Passport:
			return dto.DocumentTypePassport.String()
		case dto.LivingPermits:
			return dto.DocumentTypeResidence.String()
		case dto.DrivingLicense:
			return dto.DocumentTypeDriver.String()
		case dto.Bill:
			return dto.DocumentTypeBill.String()
		}

		return dto.DocumentTypeUnknown.String()
	} else {
		switch dt {
		case dto.ID:
			return dto.JUMIODocumentTypeID.String()
		case dto.Passport:
			return dto.JUMIODocumentTypePassport.String()
		case dto.DrivingLicense:
			return dto.JUMIODocumentTypeDriver.String()
		case dto.DocTypeCC:
			return dto.JUMIODocumentTypeCC.String()
		case dto.DocTypeBS:
			return dto.JUMIODocumentTypeBS.String()
		case dto.DocTypeIC:
			return dto.JUMIODocumentTypeIC.String()
		case dto.DocTypeUB:
			return dto.JUMIODocumentTypeUB.String()
		case dto.DocTypeCAAP:
			return dto.JUMIODocumentTypeCAAP.String()
		case dto.DocTypeCRC:
			return dto.JUMIODocumentTypeCRC.String()
		case dto.DocTypeCCS:
			return dto.JUMIODocumentTypeCCS.String()
		case dto.DocTypeLAG:
			return dto.JUMIODocumentTypeLAG.String()
		case dto.DocTypeLOAP:
			return dto.JUMIODocumentTypeLOAP.String()
		case dto.DocTypeMOAP:
			return dto.JUMIODocumentTypeMOAP.String()
		case dto.DocTypeTR:
			return dto.JUMIODocumentTypeTR.String()
		case dto.DocTypeVT:
			return dto.JUMIODocumentTypeVT.String()
		case dto.DocTypeVC:
			return dto.JUMIODocumentTypeVC.String()
		case dto.DocTypeSTUC:
			return dto.JUMIODocumentTypeSTUC.String()
		case dto.DocTypeHCC:
			return dto.JUMIODocumentTypeHCC.String()
		case dto.DocTypeCB:
			return dto.JUMIODocumentTypeCB.String()
		case dto.DocTypeSENC:
			return dto.JUMIODocumentTypeSENC.String()
		case dto.DocTypeMEDC:
			return dto.JUMIODocumentTypeMEDC.String()
		case dto.DocTypeBC:
			return dto.JUMIODocumentTypeBC.String()
		case dto.DocTypeWWCC:
			return dto.JUMIODocumentTypeWWCC.String()
		case dto.DocTypeSS:
			return dto.JUMIODocumentTypeSS.String()
		case dto.DocTypeTAC:
			return dto.JUMIODocumentTypeTAC.String()
		case dto.DocTypeSEL:
			return dto.JUMIODocumentTypeSEL.String()
		case dto.DocTypePB:
			return dto.JUMIODocumentTypePB.String()
		case dto.DocTypeSSC:
			return dto.JUMIODocumentTypeSSC.String()
		case dto.DocTypeCUSTOM:
			return dto.JUMIODocumentTypeCUSTOM.String()
		case dto.DocTypeOTHER:
			return dto.JUMIODocumentTypeOTHER.String()
		}
	}
	return ""
}

const (
	TypeEncode = iota
	TypeDecode
)

// HashUserID hash user id
func HashUserID(memberID int, p dto.KYCProvider) (token string, err error) {
	hd := hashids.NewData()
	hd.Salt = p.String()
	hd.MinLength = 20
	h, _ := hashids.NewWithData(hd)

	token, err = h.Encode([]int{memberID})
	token = processForTestEnv(token, TypeEncode)
	return
}

func processForTestEnv(hashID string, processType int) string {
	env := os.Getenv("ENVIRONMENT")
	if !strings.Contains(env, "-test-") {
		return hashID
	}

	if processType == TypeEncode {
		return hashID + "_" + env
	} else {
		items := strings.Split(hashID, "_")
		if len(items) == 0 {
			return ""
		} else {
			return items[0]
		}
	}
}
